package com.zhang.family_doctor.service.impl;

import com.zhang.family_doctor.dto.ResidentDto;
import com.zhang.family_doctor.dto.ResidentFilesDto;
import com.zhang.family_doctor.entity.*;
import com.zhang.family_doctor.mapper.ResidentMapper;
import com.zhang.family_doctor.mapper.ResidentTagMapper;
import com.zhang.family_doctor.service.ResidentService;
import com.zhang.family_doctor.utils.CommonUtils;
import com.zhang.family_doctor.utils.TokenUtils;
import com.zhang.family_doctor.utils.ValidateCodeUtils;
import com.zhang.family_doctor.vo.ResidentVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;

@Service
@Slf4j
public class ResidentServiceImpl implements ResidentService {


    @Autowired
    private ResidentMapper residentMapper;

    @Autowired
    private ResidentTagMapper residentTagMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public R<String> sendMsg(String phone) {

        //校验手机号
        Matcher matcher = CommonUtils.getPhone(phone);
        boolean matches = matcher.matches();
        if (matches) {
            Object codeInSession = redisTemplate.opsForValue().get(phone);
            if (codeInSession == null) {
                if (StringUtils.isNotEmpty(phone)) {
                    //生成随机的4位验证码
                    String code = ValidateCodeUtils.generateValidateCode(4).toString();
                    log.info("code={}", code);
                    //将我们生成的验证码保存在Redis中，并且设置有效期为1分钟
                    redisTemplate.opsForValue().set(phone, code, 1, TimeUnit.MINUTES);
                    return R.success("手机验证码短信发送成功,有效期一分钟！");
                }
            } else {
                return R.buildFailure("已经存在验证码！请等一分钟！");
            }
        } else {
            return R.buildFailure("手机号格式不对！");
        }
        return R.buildFailure("发送失败！");
    }


    /**
     * 注册居民
     *
     * @param resident
     * @return
     */
    @Override
    public R<Map<String, Object>> register(Resident resident) {

        String phone = resident.getPhone();
        String code = resident.getCode();
        Object codeInSession = redisTemplate.opsForValue().get(phone);
        Resident residentByPhone = residentMapper.getResidentByPhone(phone);
        if (residentByPhone != null) {
            //清除redis验证码
            redisTemplate.delete(phone);
            return R.buildFailure("该手机号已经注册！请换一个手机号！");
        }
        if (codeInSession != null && codeInSession.equals(code)) {
            Integer id = CommonUtils.genUUID();

            resident.setId(id);
            resident.setNumber(CommonUtils.genUUID());
            resident.setSource(1);
            resident.setCreateTime(new Date());
            resident.setUpdateTime(new Date());
            residentMapper.register(resident);
            //注册成功删除redis的验证码
            redisTemplate.delete(phone);

            Map<String, Object> map = new HashMap();
            String tokenResident = TokenUtils.signResident(resident);
            map.put("tokenResident:", tokenResident);
            //将我们生成的token保存在Redis中，并且设置有效期为6小时
            redisTemplate.opsForValue().set("tokenResident", tokenResident, 1 * 6 * 60, TimeUnit.MINUTES);
            return R.success(map);
        }
        return R.buildFailure("注册失败！");
    }

    @Override
    public R<String> newFile(Resident resident, HttpServletRequest request) {

        String idCard = resident.getIdCard();

        String name = resident.getName();
        if (name != null) {
            //真实校验姓名
            Matcher matcherName = CommonUtils.getName(name);
            boolean matchesName = matcherName.matches();
            if (matchesName) {
                if (idCard != null) {
                    //校验身份证
                    Matcher matcher = CommonUtils.getIdCard(idCard);
                    boolean matches = matcher.matches();
                    if (matches) {
                        String tokenResident = request.getHeader("tokenResident");
                        String getPhone = TokenUtils.verifyAndGetPhone(tokenResident);
                        resident.setPhone(getPhone);
                        resident.setUpdateTime(new Date());
                        residentMapper.newFile(resident);
                        return R.success("新建档案成功！");
                    } else {
                        return R.buildFailure("身份证号不符合规范！");
                    }
                } else {
                    String tokenResident = request.getHeader("tokenResident");
                    String getPhone = TokenUtils.verifyAndGetPhone(tokenResident);
                    resident.setPhone(getPhone);
                    resident.setUpdateTime(new Date());
                    residentMapper.newFile(resident);
                    return R.success("新建档案成功！");
                }
            } else {
                return R.buildFailure("真实姓名不规范！");
            }
        } else {
            if (idCard != null) {
                Matcher matcher = CommonUtils.getIdCard(idCard);
                boolean matches = matcher.matches();
                if (matches) {
                    String tokenResident = request.getHeader("tokenResident");
                    String getPhone = TokenUtils.verifyAndGetPhone(tokenResident);
                    resident.setPhone(getPhone);
                    resident.setUpdateTime(new Date());
                    residentMapper.newFile(resident);
                    return R.success("新建档案成功！");
                } else {
                    return R.buildFailure("身份证号不符合规范！");
                }
            } else {
                String tokenResident = request.getHeader("tokenResident");
                String getPhone = TokenUtils.verifyAndGetPhone(tokenResident);
                resident.setPhone(getPhone);
                resident.setUpdateTime(new Date());
                residentMapper.newFile(resident);
                return R.success("新建档案成功！");
            }
        }
    }

    @Override
    public R login(String phone, String password) {

        Resident resident = new Resident();
        resident.setPhone(phone);
        resident.setPassword(password);

        Map map = new HashMap();

        Resident residentVO = residentMapper.getResidentByPhone(phone);
        if (residentVO == null) {
            map.put("tokenResident:", null);
            map.put("msg", "居民不存在！");
            return R.success(map);
        }
        String pwd = residentVO.getPassword();
        if (!pwd.equals(password)) {
            map.put("tokenResident:", null);
            map.put("msg:", "密码错误！");
            return R.success(map);
        }
        String tokenResident = TokenUtils.signResident(residentVO);
        map.put("tokenResident:", tokenResident);
        //将我们生成的token保存在Redis中，并且设置有效期为6小时
        redisTemplate.opsForValue().set("tokenResident", tokenResident, 1 * 6 * 60, TimeUnit.MINUTES);
        return R.success(map);
    }

    @Override
    public R noLogin(String phone, String code) {

        Map map = new HashMap();
        Object codeInSession = redisTemplate.opsForValue().get(phone);
        Resident residentVO = residentMapper.getResidentByPhone(phone);
        if (residentVO == null) {
            map.put("tokenResident:", null);
            map.put("msg", "居民不存在！");
            return R.success(map);
        }
        if (codeInSession != null && codeInSession.equals(code)) {
            String tokenResident = TokenUtils.signResident(residentVO);
            //清除验证码
            redisTemplate.delete(phone);
            map.put("tokenResident:", tokenResident);
            //将我们生成的token保存在Redis中，并且设置有效期为6小时
            redisTemplate.opsForValue().set("tokenResident", tokenResident, 1 * 6 * 60, TimeUnit.MINUTES);
            return R.success(map);
        }
        return R.buildFailure("登录失败！");
    }

    @Override
    public R forgotPassword(ResidentVO residentVO) {

        String phone = residentVO.getPhone();
        String code = residentVO.getCode();
        String passwordOne = residentVO.getPasswordOne();
        String passwordTwo = residentVO.getPasswordTwo();
        Object codeInSession = redisTemplate.opsForValue().get(phone);
        Resident resident = residentMapper.getResidentByPhone(phone);
        if (resident == null) {
            return R.buildFailure("没有该用户！请注册！");
        }
        if (codeInSession != null && codeInSession.equals(code)) {
            if (passwordOne.equals(passwordTwo)) {
                residentMapper.forgotPassword(passwordTwo, phone);
                return R.success("修改成功!");
            } else {
                return R.buildFailure("两次的密码不一致！请重新输入！");
            }
        }
        return R.buildFailure("修改失败！");
    }

    /**
     * 补全或更新居民信息
     *
     * @param residentDto
     * @param request
     * @return
     */
    @Override
    public R<String> completionOrUpdate(ResidentDto residentDto, HttpServletRequest request) {

        String tokenResident = request.getHeader("tokenResident");
        String getId = TokenUtils.verifyAndGetId(tokenResident);
        Integer integer = Integer.valueOf(getId);
        Resident resident = residentDto.getResident();
        ResidentHealth residentHealth = residentDto.getResidentHealth();

        resident.setId(integer);
        resident.setUpdateTime(new Date());
        residentMapper.completionOrUpdateResident(resident);

        ResidentHealth residentHealthByResidentId = residentMapper.getResidentHealthByResidentId(integer);

        if (residentHealthByResidentId == null) {

            residentHealth.setId(CommonUtils.genUUID());
            residentHealth.setResidentId(integer);
            residentHealth.setCreateTime(new Date());
            residentHealth.setUpdateTime(new Date());
            residentMapper.saveResidentHealth(residentHealth);
            return R.success("居民基础信息修改成功和居民健康信息插入成功！");
        } else {
            Integer residentHealthId = residentHealthByResidentId.getId();
            residentHealth.setId(residentHealthId);
            residentHealth.setUpdateTime(new Date());
            residentMapper.updateResidentHealthById(residentHealth);
            return R.success("居民基础信息修改成功和居民健康信息修改成功！");
        }
    }

    /**
     * 根据token中的居民id查询居民基础信息
     *
     * @param request
     * @return
     */
    @Override
    public R<Resident> getResidentById(HttpServletRequest request) {

        String tokenResident = request.getHeader("tokenResident");
        Integer getId = Integer.valueOf(TokenUtils.verifyAndGetId(tokenResident));

        Resident residentById = residentMapper.getResidentById(getId);

        return R.success(residentById);
    }

    /**
     * 根据token中的居民id查询居民健康信息
     *
     * @param request
     * @return
     */
    @Override
    public R<ResidentHealth> getResidentHealthByResidentId(HttpServletRequest request) {

        String tokenResident = request.getHeader("tokenResident");
        Integer residentId = Integer.valueOf(TokenUtils.verifyAndGetId(tokenResident));
        ResidentHealth residentHealthByResidentId = residentMapper.getResidentHealthByResidentId(residentId);
        return R.success(residentHealthByResidentId);
    }

    /**
     * 居民新增家庭成员
     *
     * @param memberFamily
     * @param request
     * @return
     */
    @Override
    @Transactional  //添加事务
    public R<String> addMemberFamily(MemberFamily memberFamily, HttpServletRequest request) {

        String tokenResident = request.getHeader("tokenResident");
        Integer residentId = Integer.valueOf(TokenUtils.verifyAndGetId(tokenResident));

        int id = CommonUtils.genUUID();

        int familyId = CommonUtils.genUUID();

        Resident resident = memberFamily.getResident();

        String idCard = resident.getIdCard();

        String name = resident.getName();

        String phone = resident.getPhone();

        if (StringUtils.isEmpty(phone)) {
            return R.buildFailure("没有填写手机号！");
        }
        //校验手机号
        Matcher matcherPhone = CommonUtils.getPhone(phone);
        boolean matchesPhone = matcherPhone.matches();
        if (matchesPhone) {
            Resident residentByPhone = residentMapper.getResidentByPhone(phone);
            if (residentByPhone != null) {
                return R.buildFailure("该手机号已经绑定了别的居民了，请换一个手机号！");
            }
            if (StringUtils.isEmpty(name)) {
                return R.buildFailure("没有填写名字");
            }
            //真实校验姓名
            Matcher matcherName = CommonUtils.getName(name);
            boolean matchesName = matcherName.matches();
            if (matchesName) {
                if (StringUtils.isEmpty(idCard)) {
                    return R.buildFailure("没有填写身份证号！");
                }
                //校验身份证
                Matcher matcher = CommonUtils.getIdCard(idCard);
                boolean matches = matcher.matches();
                if (matches) {
                    resident.setId(id);
                    resident.setNumber(CommonUtils.genUUID());
                    resident.setSource(3);
                    resident.setCreateTime(new Date());
                    resident.setUpdateTime(new Date());
                    residentMapper.saveResident(resident);

                    Integer setDefault = memberFamily.getSetDefault();
                    if (setDefault == 1) {
                        MemberFamily memberFamilyBySetDefault = residentMapper.getMemberFamilyBySetDefault(residentId, setDefault);
                        Integer familyBySetDefaultId = memberFamilyBySetDefault.getId();

                        Integer defaults = 2;
                        residentMapper.updateMemberFamilyById(familyBySetDefaultId, defaults);

                        memberFamily.setId(familyId);
                        memberFamily.setCurrentId(residentId);
                        memberFamily.setMemberId(id);
                        memberFamily.setCreateTime(new Date());
                        residentMapper.saveMemberFamily(memberFamily);
                    } else {
                        memberFamily.setId(familyId);
                        memberFamily.setCurrentId(residentId);
                        memberFamily.setMemberId(id);
                        memberFamily.setCreateTime(new Date());
                        residentMapper.saveMemberFamily(memberFamily);
                    }
                    return R.success("新增成功！");
                } else {
                    return R.buildFailure("身份证的格式不对！");
                }
            } else {
                return R.buildFailure("名字的格式不对！");
            }
        } else {
            return R.buildFailure("该手机好格式不对请输入有效的手机好！");
        }
    }

    @Override
    @Transactional  //添加事务
    public R<String> setDefault(Integer id, Integer setDefault, HttpServletRequest request) {

        String tokenResident = request.getHeader("tokenResident");
        Integer residentId = Integer.valueOf(TokenUtils.verifyAndGetId(tokenResident));

        if (setDefault == 1) {
            MemberFamily memberFamilyBySetDefault = residentMapper.getMemberFamilyBySetDefault(residentId, setDefault);
            if (memberFamilyBySetDefault != null) {
                Integer familyBySetDefaultId = memberFamilyBySetDefault.getId();
                if (familyBySetDefaultId.equals(id)) {
                    return R.buildFailure("已经是默认");
                }
                Integer setDefaultId = 2;
                residentMapper.updateMemberFamilyById(familyBySetDefaultId, setDefaultId);
                residentMapper.updateMemberFamilyById(id, setDefault);
                return R.success("设置成功！");
            } else {
                residentMapper.updateMemberFamilyById(id, setDefault);
                return R.success("设置成功！");
            }
        } else if (setDefault == 2) {
            residentMapper.updateMemberFamilyById(id, setDefault);
            return R.success("取消默认成功！");
        } else {
            return R.buildFailure("没有该类型！");
        }
    }

    /**
     * 后台新建居民档案基本信息
     *
     * @param residentFilesDto
     * @return
     */
    @Override
    @Transactional  //添加事务
    public R<String> backgroundNewResidentFiles(ResidentFilesDto residentFilesDto) {

        Resident resident = residentFilesDto.getResident();
        List<ResidentTag> residentTagList = residentFilesDto.getResidentTagList();
        List<MemberFamily> memberFamilyList = residentFilesDto.getMemberFamilyList();

        String phone = resident.getPhone();
        String idCard = resident.getIdCard();
        String name = resident.getName();

        Resident residentByPhone = residentMapper.getResidentByPhone(phone);
        if (residentByPhone != null) {
            return R.buildFailure("该手机号已经绑定了别的居民了，请换一个手机号！");
        }

        int id = CommonUtils.genUUID();

        //校验
        Matcher matcherName = CommonUtils.getName(name);
        boolean matchesName = matcherName.matches();
        Matcher matcherPhone = CommonUtils.getPhone(phone);
        boolean matchesPhone = matcherPhone.matches();
        Matcher matcherIdCard = CommonUtils.getIdCard(idCard);
        boolean matchesIdCard = matcherIdCard.matches();

        if (matchesName) {
            if (matchesPhone) {
                if (matchesIdCard) {
                    //居民信息
                    resident.setId(id);
                    resident.setNumber(CommonUtils.genUUID());
                    resident.setCreateTime(new Date());
                    resident.setUpdateTime(new Date());
                    //后台添加
                    resident.setSource(2);
                    residentMapper.saveResident(resident);
                    //批量居民标签
                    for (ResidentTag residentTag : residentTagList) {
                        residentTag.setId(CommonUtils.genUUID());
                        residentTag.setResidentId(id);
                    }
                    residentTagMapper.saveList(residentTagList);

                    if (memberFamilyList != null && memberFamilyList.size() > 0) {

                        for (MemberFamily memberFamily : memberFamilyList) {
                            //关联家庭成员
                            memberFamily.setId(CommonUtils.genUUID());
                            memberFamily.setCreateTime(new Date());
                            memberFamily.setCurrentId(id);
                            //不设为默认
                            memberFamily.setSetDefault(2);
                        }

                        residentMapper.saveListMemberFamily(memberFamilyList);
                    }

                    return R.success("新建档案成功！");

                } else {
                    R.buildFailure("身份证格式不对！");
                }
            } else {
                R.buildFailure("手机号格式不对！");
            }
        } else {
            R.buildFailure("名字格式不对！");
        }
        return R.buildFailure("新建居民档案失败！");
    }

    /**
     * 后台新建完善的居民档案
     *
     * @param residentFilesDto
     * @return
     */
    @Override
    @Transactional  //添加事务
    public R<String> improveResidentArchives(ResidentFilesDto residentFilesDto) {

        //居民健康信息
        ResidentHealth residentHealth = residentFilesDto.getResidentHealth();
        //居民基本信息
        Resident resident = residentFilesDto.getResident();
        //居民标签
        List<ResidentTag> residentTagList = residentFilesDto.getResidentTagList();
        //家庭成员
        List<MemberFamily> memberFamilyList = residentFilesDto.getMemberFamilyList();

        String phone = resident.getPhone();
        String idCard = resident.getIdCard();
        String name = resident.getName();
        int id = CommonUtils.genUUID();

        Resident residentByPhone = residentMapper.getResidentByPhone(phone);
        if (residentByPhone != null) {
            return R.buildFailure("该手机号已经绑定了别的居民了，请换一个手机号！");
        }
        //校验
        Matcher matcherPhone = CommonUtils.getPhone(phone);
        Matcher matcherIdCard = CommonUtils.getIdCard(idCard);
        Matcher matcherName = CommonUtils.getName(name);
        boolean matchesPhone = matcherPhone.matches();
        boolean matchesIdCard = matcherIdCard.matches();
        boolean matchesName = matcherName.matches();

        if (matchesPhone) {
            if (matchesIdCard) {
                if (matchesName) {
                    //居民信息
                    resident.setId(id);
                    resident.setNumber(CommonUtils.genUUID());
                    resident.setCreateTime(new Date());
                    resident.setUpdateTime(new Date());
                    //后台添加
                    resident.setSource(2);
                    residentMapper.saveResidentFiles(resident);

                    //居民健康信息
                    residentHealth.setId(CommonUtils.genUUID());
                    residentHealth.setResidentId(id);
                    residentHealth.setCreateTime(new Date());
                    residentHealth.setUpdateTime(new Date());
                    residentMapper.saveResidentHealth(residentHealth);

                    //批量居民标签
                    for (ResidentTag residentTag : residentTagList) {
                        residentTag.setId(CommonUtils.genUUID());
                        residentTag.setResidentId(id);
                    }
                    residentTagMapper.saveList(residentTagList);
                    if (memberFamilyList != null && memberFamilyList.size() > 0) {

                        for (MemberFamily memberFamily : memberFamilyList) {
                            //关联家庭成员
                            memberFamily.setId(CommonUtils.genUUID());
                            memberFamily.setCreateTime(new Date());
                            memberFamily.setCurrentId(id);
                            //不设为默认
                            memberFamily.setSetDefault(2);
                        }

                        residentMapper.saveListMemberFamily(memberFamilyList);
                    }

                    return R.success("新建档案成功！");

                } else {
                    return R.buildFailure("名字格式不对！");
                }
            } else {
                return R.buildFailure("身份证格式不对！");
            }
        } else {
            return R.buildFailure("手机号格式不对！");
        }
    }

    /**
     * 后台修改居民信息
     *
     * @param residentFilesDto
     * @return
     */
    @Override
    @Transactional  //添加事务
    public R<String> updateResident(ResidentFilesDto residentFilesDto) {

        //居民基础信息
        Resident resident = residentFilesDto.getResident();
        //居民健康信息
        ResidentHealth residentHealth = residentFilesDto.getResidentHealth();
        //居民标签
        List<ResidentTag> residentTagList = residentFilesDto.getResidentTagList();
        //居民家庭成员
        List<MemberFamily> memberFamilyList = residentFilesDto.getMemberFamilyList();
        //居民id
        Integer id = resident.getId();
        //更新居民基础信息
        resident.setUpdateTime(new Date());
        residentMapper.updateResident(resident);
        //更新居民健康信息
        residentHealth.setResidentId(id);
        residentHealth.setUpdateTime(new Date());
        residentMapper.updateResidentHealthByResidentId(residentHealth);
        //根据居民id清除所有的居民标签
        residentTagMapper.delete(id);

        //批量插入居民标签
        residentTagList.forEach(residentTag -> {
            residentTag.setId(CommonUtils.genUUID());
            residentTag.setResidentId(id);
        });
        residentTagMapper.saveList(residentTagList);

        //根据居民id清除家庭成员
        residentMapper.deleteMemberFamilyByResidentId(id);

        //批量添加家庭成员
        memberFamilyList.forEach(memberFamily -> {
            memberFamily.setId(CommonUtils.genUUID());
            memberFamily.setCreateTime(new Date());
            memberFamily.setCurrentId(id);
            //不设为默认
            memberFamily.setSetDefault(2);
        });
        residentMapper.saveListMemberFamily(memberFamilyList);

        return R.success("修改成功！");
    }

}